﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kooboo.Commerce.Domain;
using System.Diagnostics.Contracts;
using Kooboo.Collections;

namespace Kooboo.Commerce.Repositories
{
    public partial class EntityFactory
    {
        #region Order

        public IQueryable<IOrder> Orders
        {
            get
            {
                return this.DataReaderContext.Orders
                    .Where(i => i.OrderStatus > (int)OrderStatus.Shopping);
            }
        }

        public void Post(IOrder order)
        {
            Contract.Requires(order != null);

            Order item;

            if (order.Cart == null)
            {
                item = new Order();
            }
            else
            {
                item = this.DataWriterContext.Orders.Where(i => i.Id == order.Cart.Id).FirstOrDefault();
                item.OrderItems.Clear();
            }

            item.CreateDate = DateTime.Now;

            item.Address1 = order.Address1;
            item.Address2 = order.Address2;
            item.City = order.City;
            item.CountryCode = order.Country == null ? null : order.Country.CountryCode;
            item.Coupon = order.Coupon;
            if (order.Customer == null)
            {
                item.CustomerId = null;
            }
            else
            {
                item.CustomerId = order.Customer.Id;
            }

            item.EmailAddress = order.EmailAddress;
            item.FirstName = order.FirstName;
            item.InsuredAmount = order.InsuredAmount;
            item.InvoiceAddress1 = order.InvoiceAddress1;
            item.InvoiceAddress2 = order.InvoiceAddress2;
            item.InvoiceCity = order.InvoiceCity;
            item.InvoiceCountryCode = order.InvoiceCountry == null ? null : order.InvoiceCountry.CountryCode;
            item.InvoiceFirstName = order.InvoiceFirstName;
            item.InvoiceLastName = order.InvoiceLastName;
            item.InvoicePhone = order.InvoicePhone;
            item.InvoicePostcode = order.InvoicePostcode;
            item.InvoiceState = order.InvoiceState;
            item.IsCompleted = false;
            item.LastName = order.LastName;
            item.OrderDate = order.OrderDate;
            item.OrderDiscount = order.OrderDiscount;
            item.OrderStatus = (int)order.OrderStatus;
            item.PaymentMethodCost = order.PaymentMethodCost;
            item.PaymentName = order.PaymentName;
            item.PaymentStatus = (int)PaymentStatus.Waiting;
            item.Phone = order.Phone;
            item.Postcode = order.Postcode;
            item.Remark = order.Remark;
            item.ShippingCost = order.ShippingCost;
            item.ShippingName = order.ShippingName;
            item.ShippingOptionName = order.ShippingOptionName;
            item.ShippingTrackingCode = order.ShippingTrackingCode;
            item.State = order.State;
            item.SubTotal = order.SubTotal;
            item.Total = order.Total;
            item.TotalDiscount = order.TotalDiscount;
            item.TotalTaxCost = order.TotalTaxCost;
            item.TotalWeight = order.TotalWeight;
            item.UseInvoiceAddress = order.UseInvoiceAddress;


            foreach (var i in order.OrderItems)
            {
                var orderitem = new OrderItem()
                {
                    Order = item,
                    Discount = i.Discount,
                    ProductName = i.ProductName,
                    ProductAttributes = i.ProductAttributes,
                    ProductPriceAttributes = i.ProductPriceAttributes,
                    Quantity = i.Quantity,
                    SKU = i.SKU,
                    SubTotal = i.SubTotal,
                    TaxCost = i.TaxCost,
                    Total = i.Total,
                    UnitPrice = i.UnitPrice
                };

                orderitem.ProductId = i.Product.Id;

                //if (i.ProductPriceAttributeValue == null)
                //{
                //    orderitem.ProductPriceAttributeValueId = null;
                //}
                //else
                //{
                //    orderitem.ProductPriceAttributeValueId = i.ProductPriceAttributeValue.Id;
                //}

                this.DataWriterContext.OrderItems.InsertOnSubmit(orderitem);
            }


            if (order.Cart == null)
            {
                this.DataWriterContext.Orders.InsertOnSubmit(item);
            }
            else
            {

                order.Customer = null;
                order.InvoiceCountry = null;
                order.Country = null;
                order.OrderItems = null;
            }

            this.DataWriterContext.SubmitChanges();

            order.Id = item.Id;

        }

        public void Put(IOrder order)
        {
            Contract.Requires(order != null);

            var item = this.DataWriterContext.Orders
                .Where(i => i.Id == order.Id)
                .FirstOrDefault();


            if (item == null)
            {
                throw new KeyNotFoundException("Order: " + order.Id);
            }


            item.Address1 = order.Address1;
            item.Address2 = order.Address2;
            item.City = order.City;
            item.Country = order.Country == null ? null : this.DataWriterContext.Countries.Where(i => i.CountryCode == order.Country.CountryCode).FirstOrDefault();

            item.Coupon = order.Coupon;

            if (order.Customer == null)
            {
                item.CustomerId = null;
            }
            else
            {
                item.CustomerId = order.Customer.Id;
            }

            item.EmailAddress = order.EmailAddress;
            item.FirstName = order.FirstName;
            item.InsuredAmount = order.InsuredAmount;
            item.InvoiceAddress1 = order.InvoiceAddress1;
            item.InvoiceAddress2 = order.InvoiceAddress2;
            item.InvoiceCity = order.InvoiceCity;
            item.InvoiceCountry = order.InvoiceCountry == null ? null : this.DataWriterContext.Countries.Where(i => i.CountryCode == order.Country.CountryCode).FirstOrDefault();

            item.InvoiceFirstName = order.InvoiceFirstName;
            item.InvoiceLastName = order.InvoiceLastName;
            item.InvoicePhone = order.InvoicePhone;
            item.InvoicePostcode = order.InvoicePostcode;
            item.InvoiceState = order.InvoiceState;
            item.IsCompleted = order.IsCompleted;
            item.LastName = order.LastName;
            item.OrderDate = order.OrderDate;
            item.OrderDiscount = order.OrderDiscount;
            item.OrderStatus = (int)order.OrderStatus;
            item.PaymentMethodCost = order.PaymentMethodCost;
            item.PaymentName = order.PaymentName;
            item.Phone = order.Phone;
            item.Postcode = order.Postcode;
            item.Remark = order.Remark;
            item.ShippingCost = order.ShippingCost;
            item.ShippingName = order.ShippingName;
            item.ShippingOptionName = order.ShippingOptionName;
            item.ShippingTrackingCode = order.ShippingTrackingCode;
            item.State = order.State;
            item.SubTotal = order.SubTotal;
            item.Total = order.Total;
            item.TotalDiscount = order.TotalDiscount;
            item.TotalTaxCost = order.TotalTaxCost;
            item.TotalWeight = order.TotalWeight;
            item.UseInvoiceAddress = order.UseInvoiceAddress;

            var items = this.DataWriterContext.OrderItems.Where(i => i.OrderId == item.Id).ToList();

            var result = items.Compare(order.OrderItems, (i1, i2) => i1.Id == i2.Id, (i1, i2) =>
            {
                i1.Discount = i2.Discount;
                i1.ProductName = i2.ProductName;
                i1.ProductAttributes = i2.ProductAttributes;
                i1.ProductPriceAttributes = i2.ProductPriceAttributes;
                i1.Quantity = i2.Quantity;
                i1.SKU = i2.SKU;
                i1.SubTotal = i2.SubTotal;
                i1.TaxCost = i2.TaxCost;
                i1.Total = i2.Total;
                i1.UnitPrice = i2.UnitPrice;
                i1.Product = i2.Product;
                //i1.ProductPriceAttributeValue = i2.ProductPriceAttributeValue;
            });


            foreach (var i in result.Deleted)
            {
                var find = this.DataWriterContext.OrderItems
                    .Where(n => n.Id == i.Id)
                    .FirstOrDefault();

                this.DataWriterContext.OrderItems.DeleteOnSubmit((OrderItem)i);
            }


            foreach (var i in result.Added)
            {
                var orderitem = new OrderItem()
                {
                    Order = item,
                    Discount = i.Discount,
                    ProductName = i.ProductName,
                    ProductAttributes = i.ProductAttributes,
                    ProductPriceAttributes = i.ProductPriceAttributes,
                    Quantity = i.Quantity,
                    SKU = i.SKU,
                    SubTotal = i.SubTotal,
                    TaxCost = i.TaxCost,
                    Total = i.Total,
                    UnitPrice = i.UnitPrice
                };

                orderitem.ProductId = i.Product.Id;

                //if (i.ProductPriceAttributeValue == null)
                //{
                //    orderitem.ProductPriceAttributeValueId = null;
                //}
                //else
                //{
                //    orderitem.ProductPriceAttributeValueId = i.ProductPriceAttributeValue.Id;
                //}

                this.DataWriterContext.OrderItems.InsertOnSubmit(orderitem);
            }



            this.DataWriterContext.SubmitChanges();


        }

        public void Delete(IOrder order)
        {
            if (order != null)
            {
                var item = this.DataWriterContext.Orders
                .Where(i => i.Id == order.Id)
                .FirstOrDefault();

                if (item != null)
                {
                    this.DataWriterContext.Orders.DeleteOnSubmit(item);
                    this.DataWriterContext.OrderItems.DeleteAllOnSubmit(this.DataWriterContext.OrderItems.Where(i => i.OrderId == item.Id));
                    this.DataWriterContext.SubmitChanges();
                }
            }
        }

        #endregion
    }
}
